/*
 * Copyright (C) 2022 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xjh.him.activity;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.ViewPager;

import com.alibaba.fastjson.JSON;
import com.bumptech.glide.Glide;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import com.xjh.him.R;
import com.xjh.him.activity.chat.ChatActivity;
import com.xjh.him.activity.chat.UserChooseActivity;
import com.xjh.him.adapter.entity.Session;
import com.xjh.him.common.Constant;
import com.xjh.him.core.BaseActivity;
import com.xjh.him.core.BaseFragment;
import com.xjh.him.core.netty.HandlerCallback;
import com.xjh.him.core.netty.HandlerListener;
import com.xjh.him.core.netty.NettyClient;
import com.xjh.him.core.netty.dto.FriendApplyNotifyDTO;
import com.xjh.him.core.netty.dto.UserSessionAddNotifyDTO;
import com.xjh.him.databinding.ActivityMainBinding;
import com.xjh.him.dto.UpdateNewestMsgDTO;
import com.xjh.him.dto.friendgroupmsg.FriendGroupMsgDTO;
import com.xjh.him.dto.user.UserDTO;
import com.xjh.him.dto.usergroupmsg.UserGroupMsgDTO;
import com.xjh.him.fragment.friend.FriendFragment;
import com.xjh.him.fragment.other.AboutFragment;
import com.xjh.him.fragment.other.SearchUserFragment;
import com.xjh.him.fragment.other.SettingsFragment;
import com.xjh.him.fragment.profile.ProfileFragment;
import com.xjh.him.fragment.session.SessionFragment;
import com.xjh.him.fragment.trend.DiscoverFragment;
import com.xjh.him.utils.MMKVUtils;
import com.xjh.him.utils.Utils;
import com.xjh.him.utils.XToastUtils;
import com.xuexiang.xaop.annotation.SingleClick;
import com.xuexiang.xhttp2.callback.SimpleCallBack;
import com.xuexiang.xhttp2.exception.ApiException;
import com.xuexiang.xpage.core.PageOption;
import com.xuexiang.xui.adapter.FragmentAdapter;
import com.xuexiang.xui.adapter.simple.XUISimpleAdapter;
import com.xuexiang.xui.utils.DensityUtils;
import com.xuexiang.xui.utils.ResUtils;
import com.xuexiang.xui.utils.ThemeUtils;
import com.xuexiang.xui.utils.WidgetUtils;
import com.xuexiang.xui.widget.imageview.RadiusImageView;
import com.xuexiang.xui.widget.popupwindow.popup.XUIListPopup;
import com.xuexiang.xui.widget.popupwindow.popup.XUIPopup;
import com.xuexiang.xui.widget.textview.badge.Badge;
import com.xuexiang.xui.widget.textview.badge.BadgeView;
import com.xuexiang.xutil.XUtil;
import com.xuexiang.xutil.app.ActivityUtils;
import com.xuexiang.xutil.common.ClickUtils;
import com.xuexiang.xutil.common.CollectionUtils;
import com.xuexiang.xutil.display.Colors;

import org.xjh.tool.Checks;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import io.netty.channel.ChannelHandlerContext;

/**
 * 程序主页面,只是一个简单的Tab例子
 *
 * @author xuexiang
 * @since 2019-07-07 23:53
 */
public class MainActivity extends BaseActivity<ActivityMainBinding>
        implements View.OnClickListener,
                BottomNavigationView.OnNavigationItemSelectedListener,
                ClickUtils.OnClick2ExitListener,
                Toolbar.OnMenuItemClickListener,
                HandlerListener {

    public static final String KEY_UPDATE_NEWEST_MSG_DTO = "updateNewestMsgDTO";

    /**
     * 底部 tab 标题
     */
    private String[] mTitles;

    /**
     * 添加菜单
     */
    private String[] mAddMenuItems;

    /**
     * 主页片段
     */
    private SessionFragment sessionFragment;
    private FriendFragment friendFragment;
    private DiscoverFragment discoverFragment;
    private ProfileFragment profileFragment;

    /**
     * 用户信息
     */
    public UserDTO userDTO;

    private Badge friendBadge;


    @Override
    protected ActivityMainBinding viewBindingInflate(LayoutInflater inflater) {
        return ActivityMainBinding.inflate(inflater);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initProperty();
        initViews();
        initListeners();

        HandlerCallback.subscribe(this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        String apiUrl = Utils.getWebServerApiUrl(this, getString(R.string.api_user_me));
        SimpleCallBack<UserDTO> simpleCallBack = new SimpleCallBack<UserDTO>() {
            @Override
            public void onSuccess(UserDTO response) throws Throwable {
                userDTO = response;
                //更新缓存
                MMKVUtils.put(Constant.MMKV_KEY_USER_DTO, JSON.toJSONString(response));
                //更新我的页面
                profileFragment.loadViews(userDTO);
                //更新header
                updateHeader(userDTO);
            }

            @Override
            public void onError(ApiException e) {
                XToastUtils.error(e.getDisplayMessage());
            }
        };
        Utils.doGet(apiUrl, simpleCallBack);
    }

    @Override
    protected boolean isSupportSlideBack() {
        return false;
    }

    private void initProperty() {
        mTitles = ResUtils.getStringArray(R.array.home_titles);
        mAddMenuItems = ResUtils.getStringArray(R.array.home_add_menu_items);
        String json = (String) MMKVUtils.get(Constant.MMKV_KEY_USER_DTO, "");
        if (!Checks.isEmpty(json)) {
            userDTO = JSON.parseObject(json, UserDTO.class);
        }

        sessionFragment = new SessionFragment();
        friendFragment = new FriendFragment();
        discoverFragment = new DiscoverFragment();
        profileFragment = new ProfileFragment(userDTO);
    }

    private void initViews() {
        WidgetUtils.clearActivityBackground(this);

        binding.includeMain.toolbarTitle.setText(mTitles[0]);
        binding.includeMain.toolbar.inflateMenu(R.menu.menu_main);
        binding.includeMain.toolbar.setOnMenuItemClickListener(this);

        initHeader();

        //主页内容填充
        List<BaseFragment> fragmentList = new ArrayList<>();
        fragmentList.addAll(Arrays.asList(
                sessionFragment, friendFragment,
                discoverFragment, profileFragment
        ));
        FragmentAdapter<BaseFragment> adapter = new FragmentAdapter<>(getSupportFragmentManager(), fragmentList);
        binding.includeMain.viewPager.setOffscreenPageLimit(mTitles.length - 1);
        binding.includeMain.viewPager.setAdapter(adapter);
    }

    private void initHeader() {
        binding.navView.setItemIconTintList(null);
        View headerView = binding.navView.getHeaderView(0);
        LinearLayout navHeader = headerView.findViewById(R.id.nav_header);
        RadiusImageView ivAvatar = headerView.findViewById(R.id.iv_header);
        TextView tvNickname = headerView.findViewById(R.id.tv_nickname);
        TextView tvSign = headerView.findViewById(R.id.tv_sign);

        if (Utils.isColorDark(ThemeUtils.resolveColor(this, R.attr.colorAccent))) {
            tvNickname.setTextColor(Colors.WHITE);
            tvSign.setTextColor(Colors.WHITE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                ivAvatar.setImageTintList(ResUtils.getColors(R.color.xui_config_color_white));
            }
        }else {
            tvNickname.setTextColor(ThemeUtils.resolveColor(this, R.attr.xui_config_color_title_text));
            tvSign.setTextColor(ThemeUtils.resolveColor(this, R.attr.xui_config_color_explain_text));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                ivAvatar.setImageTintList(ResUtils.getColors(R.color.xui_config_color_gray_3));
            }
        }

        if (userDTO != null) {
            Glide.with(this).load(userDTO.getAvatarUrl()).into(ivAvatar);
            tvNickname.setText(userDTO.getNickname());
            tvSign.setText(userDTO.getSignature());
        }else {
            ivAvatar.setImageResource(R.drawable.ic_default_head);
            tvNickname.setText(R.string.app_name);
        }
        navHeader.setOnClickListener(this);
    }

    /**
     * 更新 header
     */
    public void updateHeader(UserDTO userDTO) {
        NavigationView navView = findViewById(R.id.nav_view);
        View headerView = navView.getHeaderView(0);
        RadiusImageView ivAvatar = headerView.findViewById(R.id.iv_header);
        TextView tvNickname = headerView.findViewById(R.id.tv_nickname);
        TextView tvSign = headerView.findViewById(R.id.tv_sign);
        Glide.with(this).load(userDTO.getAvatarUrl()).into(ivAvatar);
        tvNickname.setText(userDTO.getNickname());
        tvSign.setText(userDTO.getSignature());
    }

    protected void initListeners() {
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, binding.drawerLayout, binding.includeMain.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        binding.drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        //侧边栏点击事件
        binding.navView.setNavigationItemSelectedListener(menuItem -> {
            if (menuItem.isCheckable()) {
                binding.drawerLayout.closeDrawers();
                return handleNavigationItemSelected(menuItem);
            } else {
                int id = menuItem.getItemId();
                if (id == R.id.nav_settings) {
                    openNewPage(SettingsFragment.class);
                } else if (id == R.id.nav_about) {
                    openNewPage(AboutFragment.class);
                } else {
                    XToastUtils.toast("点击了:" + menuItem.getTitle());
                }
            }
            return true;
        });
        //主页事件监听
        binding.includeMain.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                MenuItem item = binding.includeMain.bottomNavigation.getMenu().getItem(position);
                if (item.getItemId() == R.id.nav_profile) {
                }else if (item.getItemId() == R.id.nav_friend) {
                    if (friendBadge != null) {
                        friendBadge.hide(true);
                    }
                }
                item.setChecked(true);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        binding.includeMain.bottomNavigation.setOnNavigationItemSelectedListener(this);
    }

    /**
     * 处理侧边栏点击事件
     *
     * @param menuItem
     * @return
     */
    private boolean handleNavigationItemSelected(@NonNull MenuItem menuItem) {
        int index = CollectionUtils.arrayIndexOf(mTitles, menuItem.getTitle());
        if (index != -1) {
            binding.includeMain.toolbar.setTitle(menuItem.getTitle());
            binding.includeMain.viewPager.setCurrentItem(index, false);
            return true;
        }
        return false;
    }

    /**
     * toolbar 右侧菜单点击
     * @param item
     * @return
     */
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_add) {
            XUISimpleAdapter adapter = XUISimpleAdapter.create(this, mAddMenuItems);
            XUIListPopup mListPopup = new XUIListPopup(this, adapter);
            mListPopup.create(DensityUtils.dp2px(150), DensityUtils.dp2px(150), new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if (position == 0) {
                        //发起群聊
                        ActivityUtils.startActivity(
                                UserChooseActivity.class,
                                UserChooseActivity.KEY_ACTIVITY_TARGET,
                                UserChooseActivity.ACTIVITY_TARGET_CREATE_GROUP
                        );
                    }else if (position == 1) {
                        //添加好友
                        PageOption.to(SearchUserFragment.class)
                                .setNewActivity(true)
                                .open(MainActivity.this);
                    }
                    mListPopup.dismiss();
                }
            });
            mListPopup.setAnimStyle(XUIPopup.ANIM_GROW_FROM_CENTER);
            mListPopup.setPreferredDirection(XUIPopup.DIRECTION_BOTTOM);
            mListPopup.show(binding.includeMain.toolbar.findViewById(R.id.action_add));
        }
        return false;
    }

    @SingleClick
    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.nav_view) {
            XToastUtils.toast("展开侧边栏");
        }
    }

    //================Navigation================//

    /**
     * 底部导航栏点击事件
     *
     * @param menuItem
     * @return
     */
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        int index = CollectionUtils.arrayIndexOf(mTitles, menuItem.getTitle());
        if (index != -1) {
            if (menuItem.getItemId() == R.id.nav_profile) {
                binding.includeMain.toolbarTitle.setText("");
            }else {
                binding.includeMain.toolbarTitle.setText(menuItem.getTitle());
            }
            binding.includeMain.viewPager.setCurrentItem(index, false);
            return true;
        }
        return false;
    }

    /**
     * 菜单、返回键响应
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            ClickUtils.exitBy2Click(2000, this);
        }
        return true;
    }

    @Override
    public void onRetry() {
        XToastUtils.toast("再按一次退出程序");
    }

    @Override
    public void onExit() {
        NettyClient.getInstance().disconnect();
        XUtil.exitApp();
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SessionFragment.PAGE_CODE && resultCode == ChatActivity.PAGE_CODE) {
            UpdateNewestMsgDTO updateDTO = (UpdateNewestMsgDTO) data.getSerializableExtra(KEY_UPDATE_NEWEST_MSG_DTO);
            if (updateDTO != null) {
                sessionFragment.updateNewestMsg(updateDTO);
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public Boolean consume(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof FriendApplyNotifyDTO) {
            runOnUiThread(this::initFriendBadge);
            return true;
        }else if (msg instanceof UserSessionAddNotifyDTO) {
            UserSessionAddNotifyDTO addNotifyDTO = (UserSessionAddNotifyDTO) msg;
            runOnUiThread(() -> {
                Session session = new Session();
                session.setTargetId(addNotifyDTO.getTargetId());
                session.setFriendId(addNotifyDTO.getFriendId());
                session.setGroupType(addNotifyDTO.getGroupType());
                session.setGroupName(addNotifyDTO.getGroupName());
                session.setGroupAvatar(addNotifyDTO.getGroupAvatar());
                session.setIsTop(addNotifyDTO.getTop());
                session.setNewestMsg(addNotifyDTO.getNewestMsg());
                sessionFragment.addSessionItem(session);
            });
            return true;
        }else if (msg instanceof FriendGroupMsgDTO) {
            FriendGroupMsgDTO msgDTO = (FriendGroupMsgDTO) msg;
            runOnUiThread(() -> {
                UpdateNewestMsgDTO updateDTO = new UpdateNewestMsgDTO();
                updateDTO.setGroupId(msgDTO.getFriendGroupId());
                updateDTO.setGroupType(Session.GROUP_TYPE_SINGLE);
                updateDTO.setMsgType(msgDTO.getMsgType());
                updateDTO.setMsgContent(msgDTO.getMsgContent());
                sessionFragment.updateNewestMsg(updateDTO);
            });
            return true;
        }else if (msg instanceof UserGroupMsgDTO) {
            UserGroupMsgDTO msgDTO = (UserGroupMsgDTO) msg;
            runOnUiThread(() -> {
                UpdateNewestMsgDTO updateDTO = new UpdateNewestMsgDTO();
                updateDTO.setGroupId(msgDTO.getUserGroupId());
                updateDTO.setGroupType(Session.GROUP_TYPE_MULTIPLE);
                updateDTO.setSenderNickname(msgDTO.getUserNickname());
                updateDTO.setMsgType(msgDTO.getMsgType());
                updateDTO.setMsgContent(msgDTO.getMsgContent());
                sessionFragment.updateNewestMsg(updateDTO);
            });
            return true;
        }

        return false;
    }

    /**
     * 初始化底部好友申请小红点
     */
    private void initFriendBadge() {
        String countApplyUrl = Utils.getWebServerApiUrl(MainActivity.this, getString(R.string.api_friend_apply_count));
        SimpleCallBack<Integer> countCB = new SimpleCallBack<Integer>() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onSuccess(Integer count) throws Throwable {
                if (count > 0) {
                    View view = binding.includeMain.bottomNavigation.findViewById(R.id.nav_friend);
                    friendBadge = new BadgeView(MainActivity.this)
                            .bindTarget(view)
                            .setBadgeGravity(Gravity.TOP | Gravity.END)
                            .setBadgeNumber(count);
                    friendFragment.initNewFriendBadgeView();

                    //震动提醒
                    Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
                    vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
                }
            }

            @Override
            public void onError(ApiException e) {
                XToastUtils.toast(e.getDisplayMessage());
            }
        };
        Utils.doGet(countApplyUrl, countCB);
    }
}
